// 对于axios进行二次封装
import {localStorageUtils} from "@/utils/LocalStorageUtils";
import axios from "axios"
// 引入Message提示框(vue3)
import {ElMessage} from 'element-plus'
import type PathVariable from "@/domain/po/PathVariable";
import StringUtils from "@/utils/StringUtils";


// 利用axios对象的方法create，去创建一个axios实例
const axiosInstance = axios.create({
    // 配置对象
    // 基础路径。发送请求的时候，路径当中会出现api
    // baseURL: "",
    // 代表请求超时时间
    timeout: 3000,
})
// 请求拦截器：在发送请求之前，请求拦截器可以检测到，可以在发送请求之前处理一些业务
axiosInstance.interceptors.request.use((config) => {
    // config:配置对象，对象里面有一个属性很重要，header请求头
    // console.log("token的值"+getToken())
    if (localStorageUtils.getToken() != undefined) {
        config.headers['XX-Token'] = localStorageUtils.getToken()
    }
    return config;
}, (error) => {
    return Promise.reject(error);
})

// 响应拦截器
axiosInstance.interceptors.response.use(
    (res) => {
        let contentType = res.headers["content-type"] as string;
        if (StringUtils.isBlank(contentType)) {
            console.log("未返回类型" + contentType)
            return Promise.reject("未返回类型" + contentType)
        }
        contentType = contentType.split(";")[0];
        // 文件流
        if (contentType == "application/octet-stream") {
            return Promise.resolve(res.data);
        // JSON数据
        } else if (contentType == "application/json") {
            // 业务逻辑错误
            switch (res.data.code) {
                case 200:
                    return Promise.resolve(res.data.data);
                case 999: //后端报错
                    return Promise.reject(res.data)
                default:  //后端返回预期报错，前端直接提示
                    ElMessage.error({message: res.data.msg})
                    return Promise.reject(res.data)
            }
        } else {
            console.log("未知返回类型" + contentType)
            return Promise.reject("未知返回类型" + contentType)
        }
    },
    (error) => {
        // 响应失败的回调函数
        if (error.response.code == 504 || error.response.code == 404) {
            ElMessage({
                showClose: true,
                message: '服务器链接失败',
                type: 'error',
            })
        } else if (error.response.code == 403) {
            ElMessage({
                showClose: true,
                message: '权限不足，请联系管理员',
                type: 'error',
            })
        } else if (error.response.code == 401) {
            ElMessage({
                showClose: true,
                message: '尚未登陆，请登录',
                type: 'error',
            })
        } else if (error.response.code == 1004) {
            ElMessage({
                showClose: true,
                message: '请重新登录',
                type: 'error',
            })
        } else if (error.response.code == 1005) {
            ElMessage({
                showClose: true,
                message: '登录已过期，请重新登录！',
                type: 'error',
            })
        } else {
            if (error.response.data.message) {
                ElMessage({
                    showClose: true,
                    message: error.response.data.message,
                    type: 'error',
                })
            } else {
                ElMessage({
                    showClose: true,
                    message: '未知错误',
                    type: 'error',
                })
            }
        }
    }
)

export default class Requests {
    constructor(url: string) {
        this._url = url;
    }

    /**
     * 请求路径
     */
    private _url: string;

    /**
     * 构建一个Requests
     * @param url 请求路径
     */
    public static build(url: string): Requests {
        return new Requests(url);
    }

    /**
     * 参数路径
     * @param pathVariable
     */
    public pathVariable(pathVariable: PathVariable[]): Requests {
        pathVariable.forEach((item) => {
            this._url = this._url.replace("{" + item.name + "}", item.value)
        })
        return this;
    }

    /**
     * get请求
     * @param params query参数
     */
    public doGet(params: {} | undefined): Promise<any> {
        return axiosInstance.request({
            url: this._url,
            params: params,
            method: "get"
        })
    }

    /**
     * post请求
     * @param data body参数
     */
    public doPost(data: {} | undefined): Promise<any> {
        return axiosInstance.request({
            url: this._url,
            data: data,
            method: "post"
        })
    }

    /**
     * postFormData请求 通常用于文件上传
     * @param data body参数
     */
    public doPostFormData(data: {} | undefined): Promise<any> {
        return axiosInstance.request({
            url: this._url,
            data: data,
            method: "post",
            headers: {
                "Content-Type": "multipart/form-data", // 设置请求头为multipart/form-data
            }
        })
    }

    /**
     * put请求
     * @param data body参数
     */
    public doPut(data: {} | undefined): Promise<any> {
        return axiosInstance.request({
            url: this._url,
            data: data,
            method: "put"
        })
    }

    /**
     * delete请求
     * @param data body参数
     */
    public doDelete(data: {} | undefined): Promise<any> {
        return axiosInstance.request({
            url: this._url,
            data: data,
            method: "delete"
        })
    }
}

